"""PDF文件解析"""
import os
import re
import fitz
import argparse
from collections import defaultdict as def_dict


class FileHandle:
    """文件数据提取"""

    def __init__(self, path):
        """
        path: pdf文件路径
        """
        self.file = path
        self.file_name = os.path.basename(self.file)

    @staticmethod
    def _merge_block_text_into_line(block, delta=10):
        """功能：将block内容块中的内容分行
        block:内容块
        delta：同一行的y可偏移范围
        """
        words_in_line = def_dict(list)
        key = None
        ordered_words = sorted(block, key=lambda x: x[1])
        for word in ordered_words:
            y_val = int(round(word[1]))
            if key is not None and y_val in key:
                words_in_line[key].append(word)
            else:
                key = tuple([(i + y_val) for i in range(delta)])
                words_in_line[key].append(word)
        for key, words in words_in_line.items():
            str_ = ''.join(word[4] for word in sorted(words, key=lambda x: x[0]))
            str_ = str_.replace(' ', '').replace('\n', '')
            words_in_line[key] = str_

        text = ''
        words_in_line_new = {}
        for idx, (_, str_) in enumerate(sorted(words_in_line.items(), key=lambda x: x[0][0])):
            words_in_line_new[idx] = str_
            text += str_
        words_in_line_new['text'] = text
        return words_in_line_new

    def do_parse(self):
        doc = fitz.Document(self.file)
        page = doc[0]
        # first_char = sorted(page.search_for('码'), key=lambda x: x.y0)[0]
        # last_char = sorted(page.search_for('校'), key=lambda x: x.y0)[0]
        # target_rect = (last_char.x0 - 10, first_char.y0 - 10, 800, last_char.y1 + 10)
        words = page.get_text('words')
        words_inline = self._merge_block_text_into_line(words)
        inv_code = None
        inv_num = None
        inv_date = None
        inv_chk = None
        inv_money = None
        words_inline.pop('text')
        for _, line_text in words_inline.items():
            if '发票代码' in line_text:
                nums = re.findall(r'\d+', line_text)
                inv_code = ''.join(str(num) for num in nums)
            elif '发票号码' in line_text:
                nums = re.findall(r'\d+', line_text)
                inv_num = ''.join(str(num) for num in nums)
            elif '开票日期' in line_text:
                nums = re.findall(r'\d+', line_text)
                inv_date = ''.join(str(num) for num in nums)
            elif '校验码' in line_text:
                nums = re.findall(r'[a-zA-Z\d]+', line_text.split('校验码')[-1])
                inv_chk = ''.join(str(num) for num in nums)
            elif '合计' in line_text and '大写' not in line_text:
                money_list = re.findall(r'[¥￥]\d+\.\d+', line_text)
                money_str = money_list[0] if len(money_list) > 0 else ''
                inv_money = re.sub(r'[¥￥]', '', money_str)
        return inv_code, inv_num, inv_date, inv_chk, inv_money


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-p', '--path', type=str, required=True, help='输入文件路径')
    args = parser.parse_args()
    handle = FileHandle(args.path)
    data = handle.do_parse()
    print(data)
